import 'package:flutter/material.dart';
import 'package:lazy_food/components/keepAliveWrapper/keep_alive_arapper.dart';

class CalendarView extends StatefulWidget {
  final List<String>? weeks;
  final TextStyle? weekStyle;
  final DateTime? initSelectDate;
  final TextStyle? headerStyle;
  final Widget Function(DateTime)? buildHeader;
  final Widget Function(DayModel)? buildChild;
  final void Function(DayModel)? onClickDay;

  CalendarView({
    Key? key,
    this.weeks,
    this.weekStyle,
    this.headerStyle,
    this.initSelectDate,
    this.buildChild,
    this.buildHeader,
    this.onClickDay,
  }) : super(key: key);

  _CalendarViewState createState() => _CalendarViewState();
}

class _CalendarViewState extends State<CalendarView> {
  List<DayModel> _days = [];
  List<DateTime> _months = [];
  late int _currentPage;
  late List<String> _weeks;
  late DateTime _currentDate;
  late PageController _pageController;

  @override
  void initState() {
    super.initState();
    _currentDate = widget.initSelectDate ?? DateTime.now();
    _weeks = widget.weeks ?? ["日", "一", "二", "三", "四", "五", "六"];
    _loadDates(_currentDate);
    Map val = _loadMonths();
    _currentPage = val['index'];
    _months = val['months'];
    _pageController = PageController(initialPage: _currentPage);
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, constraints) {
      double row = _days.length / 7;
      double itemW = (constraints.biggest.width / 7).truncateToDouble();
      double itemH =
          ((constraints.biggest.height - 56) / (row + 1)).truncateToDouble();
      return PageView.builder(
        itemCount: _months.length,
        controller: _pageController,
        itemBuilder: (context, index) {
          return _buildCalendar(constraints, itemW, itemH);
        },
        onPageChanged: (value) {
          DateTime date = _months[value];
          if (value > _currentPage) {
            _onNextMonth();
          } else if (value < _currentPage) {
            _onLastMonth();
          }
          _currentPage = value;
        },
      );
    });
  }

  // 绘制某月的日历
  Widget _buildCalendar(
      BoxConstraints constraints, double width, double height) {
    double childAspectRatio = width / height;
    return Container(
      width: constraints.biggest.width,
      child: Column(
        children: [
          _buildHeader(_currentDate),
          SizedBox(height: 8),
          _buildWeek(constraints.biggest.width, height),
          Expanded(
            child: GridView.builder(
              physics: NeverScrollableScrollPhysics(),
              itemCount: _days.length,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 7,
                childAspectRatio: childAspectRatio,
              ),
              itemBuilder: (context, index) {
                return _buildChild(index);
              },
            ),
          ),
          SizedBox(height: 8),
        ],
      ),
    );
  }

  // 绘制Header
  Widget _buildHeader(DateTime date) {
    if (widget.buildHeader != null) {
      return Container(
        height: 40,
        child: widget.buildHeader!(date),
      );
    } else {
      String dateTitle =
          '${date.year} · ${date.month.toString().padLeft(2, '0')}';
      return Container(
        height: 40,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            IconButton(
              onPressed: _onLastMonth,
              icon: Icon(
                Icons.arrow_left_sharp,
                color: Colors.white,
              ),
            ),
            SizedBox(width: 10),
            Text(
              dateTitle,
              style: widget.headerStyle ??
                  TextStyle(color: Colors.white, fontSize: 20),
            ),
            SizedBox(width: 10),
            IconButton(
              onPressed: _onNextMonth,
              icon: Icon(
                Icons.arrow_right_sharp,
                color: Colors.white,
              ),
            ),
            SizedBox(
              width: 10,
            ),
          ],
        ),
      );
    }
  }

  // 绘制星期
  Widget _buildWeek(double width, double height) {
    TextStyle weekStyle = widget.weekStyle ??
        TextStyle(
            color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold);
    return Container(
      width: width,
      height: height,
      child: Row(
        children: _weeks.map((e) {
          return Expanded(
            child: Center(
              child: Text(
                e,
                style: weekStyle,
              ),
            ),
          );
        }).toList(),
      ),
    );
  }

  // 绘制item
  Widget _buildChild(int index) {
    DayModel day = _days[index];
    TextStyle otherStyle = TextStyle(color: Colors.white38, fontSize: 14);
    TextStyle dayStyle = TextStyle(color: Colors.white, fontSize: 14);
    TextStyle style = day.isLast || day.isNext ? otherStyle : dayStyle;
    return GestureDetector(
      child: widget.buildChild != null
          ? Center(
              child: widget.buildChild!(day),
            )
          : Center(
              child: Text(
                '${day.dateTime.day}',
                style: style,
              ),
            ),
      onTap: () {
        if (widget.onClickDay != null) {
          widget.onClickDay!(day);
        }
      },
    );
  }

  // 加载日期数据
  void _loadDates(DateTime date) {
    // 创建日期数组
    List<DayModel> days = [];
    // 获取当前月有多少天
    DateTime start = DateTime(date.year, date.month, 1);
    int weekday = start.weekday;
    DateTime end;
    if (date.month == 12) {
      end = DateTime(date.year + 1, 1, 0);
    } else {
      end = DateTime(date.year, date.month + 1, 0);
    }
    int currentNum = end.day;
    // 获取上个月有多少天
    DateTime before = DateTime(start.year, start.month, 0);
    int beforeNum = before.day;
    // 上个月
    int num = weekday == 7 ? 0 : weekday - 1;
    for (var i = num; i >= 0; i--) {
      int val = beforeNum - i;
      DateTime time = DateTime(before.year, before.month, val);
      days.add(DayModel(dateTime: time, isLast: true));
    }
    // 当前月
    for (var i = 1; i <= end.day; i++) {
      DateTime time = DateTime(start.year, start.month, i);
      days.add(DayModel(dateTime: time));
    }
    // 下个月
    int val = 0;
    if (days.length > 35) {
      val = 42 - days.length;
    } else {
      val = 35 - days.length;
    }
    for (var i = 1; i <= val; i++) {
      DateTime time = DateTime(end.year, end.month, i);
      days.add(DayModel(dateTime: time, isNext: true));
    }
    setState(() {
      _days = days;
    });
  }

  // 加载月数据
  Map<String, dynamic> _loadMonths() {
    List<DateTime> months = [];
    DateTime current = DateTime.now();
    int index = 0;
    for (var i = 1000; i < 9999; i++) {
      for (var j = 1; j < 13; j++) {
        DateTime time = DateTime(i, j, 1);
        months.add(time);
        if (time.year == current.year && time.month == current.month) {
          index = months.length - 1;
        }
      }
    }
    return {'index': index, 'months': months};
  }

  // 点击上月
  void _onLastMonth() {
    DateTime last;
    if (_currentDate.month == 1) {
      last = DateTime(_currentDate.year - 1, 12, 1);
    } else {
      last = DateTime(_currentDate.year, _currentDate.month - 1, 1);
    }
    _currentDate = last;
    _loadDates(_currentDate);
  }

  // 点击下月
  void _onNextMonth() {
    DateTime next;
    if (_currentDate.month == 12) {
      next = DateTime(_currentDate.year + 1, 1, 1);
    } else {
      next = DateTime(_currentDate.year, _currentDate.month + 1, 1);
    }
    _currentDate = next;
    _loadDates(_currentDate);
  }
}

class DayModel {
  DateTime dateTime;
  bool isWeek;
  bool isLast;
  bool isNext;

  DayModel(
      {required this.dateTime,
      this.isWeek = false,
      this.isLast = false,
      this.isNext = false});
}
